from dataclasses import asdict, dataclass
from enum import IntEnum
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel


def enum_dict_factory(inputs):
    """
    枚举类型字典工厂函数
    
    将枚举值转换为整数值的字典工厂
    
    参数:
        inputs: 包含枚举值的输入元组列表
    """
    inputs = [(i[0], i[-1].value) if isinstance(i[-1], IntEnum) else i
              for i in inputs]
    return dict(inputs)


def dataclass2dict(data):
    """
    数据类转字典函数
    
    使用自定义字典工厂将数据类转换为字典
    """
    return asdict(data, dict_factory=enum_dict_factory)


@dataclass
class FunctionCall:
    """
    函数调用数据类
    
    表示一个函数调用的结构
    
    属性:
        name (str): 函数名称
        parameters (Union[Dict, str]): 函数参数
    """
    name: str
    parameters: Union[Dict, str]


class ActionStatusCode(IntEnum):
    """
    动作状态码枚举
    
    定义了动作执行的各种状态
    """
    ING = 1            # 执行中
    SUCCESS = 0        # 执行成功
    HTTP_ERROR = -1000 # HTTP错误
    ARGS_ERROR = -1001 # 参数错误
    API_ERROR = -1002  # 未知错误


class ActionValidCode(IntEnum):
    """
    动作有效性码枚举
    
    定义了动作的有效性状态
    """
    FINISH = 1    # 完成
    OPEN = 0      # 开放
    CLOSED = -1   # 关闭
    INVALID = -2  # 无效
    ABSENT = -3   # 无动作


@dataclass
class ActionReturn:
    """
    动作返回数据类
    
    定义动作执行的返回结果结构
    
    属性:
        args: 参数字典
        url: URL字符串
        type: 动作类型
        result: 结果列表
        errmsg: 错误信息
        state: 执行状态
        thought: 思考过程
        valid: 有效性状态
    """
    args: Optional[dict] = None
    url: Optional[str] = None
    type: Optional[str] = None
    result: Optional[List[dict]] = None
    errmsg: Optional[str] = None
    state: Union[ActionStatusCode, int] = ActionStatusCode.SUCCESS
    thought: Optional[str] = None
    valid: Optional[ActionValidCode] = ActionValidCode.OPEN

    def format_result(self) -> str:
        """
        格式化结果
        
        将结果列表转换为字符串格式
        """
        result = []
        for item in self.result or []:
            if item['type'] == 'text':
                result.append(item['content'])
            else:
                result.append(f"[{item['type']}]({item['content']})")
        result = '\n'.join(result)
        return result


class ModelStatusCode(IntEnum):
    """
    模型状态码枚举
    
    定义了模型执行的各种状态
    """
    END = 0                    # 流式输出结束
    STREAM_ING = 1            # 正在流式输出
    SERVER_ERR = -1           # 服务器错误
    SESSION_CLOSED = -2       # 会话已关闭
    SESSION_OUT_OF_LIMIT = -3 # 请求长度超限
    SESSION_INVALID_ARG = -4  # 无效参数
    SESSION_READY = 2         # 会话准备就绪


class AgentStatusCode(IntEnum):
    """
    代理状态码枚举
    
    定义了代理执行的各种状态
    """
    END = 0                    # 流式输出结束
    STREAM_ING = 1            # 正在流式输出
    SERVER_ERR = -1           # 服务器错误
    SESSION_CLOSED = -2       # 会话已关闭
    SESSION_OUT_OF_LIMIT = -3 # 请求长度超限
    SESSION_INVALID_ARG = -4  # 无效参数
    SESSION_READY = 2         # 会话准备就绪
    PLUGIN_START = 3          # 工具开始执行
    PLUGIN_END = 4            # 工具执行完成
    PLUGIN_RETURN = 5         # 工具返回结果
    CODING = 6                # 开始执行Python代码
    CODE_END = 7              # Python代码执行完成
    CODE_RETURN = 8           # Python代码返回结果


class AgentMessage(BaseModel):
    """
    代理消息模型
    
    定义了代理之间传递的消息结构
    
    属性:
        content: 消息内容
        sender: 发送者名称
        formatted: 格式化后的内容
        extra_info: 额外信息
        type: 消息类型
        receiver: 接收者名称
        stream_state: 流状态
    """
    content: Any
    sender: str = 'user'
    formatted: Optional[Any] = None
    extra_info: Optional[Any] = None
    type: Optional[str] = None
    receiver: Optional[str] = None
    stream_state: Union[ModelStatusCode, AgentStatusCode] = AgentStatusCode.END
